Pyxsoft Firewall CLI Reference
Pyxsoft Firewall is currently in its beta phase. Some features may be incomplete or subject to change.
Output formats (global flags)
--json→ JSON envelope:{ ok, code, data }or{ ok:false, code, error }--yaml→ YAML envelope (same fields)- (Human mode is default if neither flag is present)
Examples:
pxf status --yaml
pxf list ports --json
Command reference
Journal-first model: most commands append to the journal and are enforced on the next
pxf apply.pxf ip allow/deny/remove-*are exceptions—they update the firewall immediately and record the change so the next apply stays in sync (the killswitchenable/disablealso acts immediately).
Status & inspection
pxf status— Backend info, desired policies, counts, killswitch flag.pxf list ports— Desired open ports/ranges (proto, any/CIDR scope).pxf list allowed-ip/pxf list blocked-ip— Bastions and global blocks.
pxf list blocked-ipshows reverse DNS and ISO country codes (where resolvable) in separate columns;--json/--yamlincludereverseandcountryfields in each item.pxf list redirects—redirect,redirect-open,tredirect,lredirect.pxf journal show [--offset N --limit M]— Paginated raw journal.pxf journal prune— Compact journal by logical key (“last wins”).pxf show-rules— Dump raw rules (nft list rulesetoriptables-save) + summary.pxf validate— Binaries, kernel modules,firewalld, root permission.pxf verify— Drift check: desired snapshot vs actual rules (policies + redirects).pxf version— Version/commit/build date.
Lifecycle
pxf apply— Recompute snapshot from journal, restore persisted IP blocks (TTL=0), and apply (idempotent).- Permanent blocks come from
/var/lib/pxf/blocked_ips.jsonl - Temporary blocks (TTL>0) are preserved across
applyby snapshotting the live firewall set before each flush, but they are not persisted to disk (lost on reboot or service restart)
- Permanent blocks come from
pxf enable— Turn off killswitch and apply the rules.pxf disable— Killswitch: runtime ALLOW ALL until re-enabled.pxf reset --allow-all— Clear journal, setDisabled=false, leave backend ALLOW ALL.
Policies & ICMP
pxf policy deny-all— Desired baselineDROPfor INPUT/FORWARD (OUTPUT stays ACCEPT). On apply, essential ICMPv4/ICMPv6 are added automatically.pxf icmp allow-essential [--v v4|v6|both]— Record minimal ICMP rules (echo, unreachable, ND/PMTU…).
Ports
-
pxf ports allow-port --port P --proto tcp|udp [--cidr A/B ...] [--comment "web app"] -
pxf ports allow-port-range --from A --to B --proto tcp|udp [--cidr ...] [--comment "..."] -
pxf ports close-port --port P --proto tcp|udp [--cidr ...] [--comment "sunset"] -
pxf ports close-port-range --from A --to B --proto tcp|udp [--cidr ...] [--comment "..."] -
Selective per-port denies (new)
pxf ports deny-from --port P --proto tcp|udp --cidr A/B [--cidr C/D ...]Deny traffic from specific source CIDR(s) to the given port/proto. Applied before NAT and before allow/bastion rules, and reinforced in filter chains for local traffic. Effective even when the port is globally open.pxf ports remove-deny-from --port P --proto tcp|udp --cidr A/B [--cidr C/D ...]Remove previously declared per-port denies.
With ACCEPT baseline, closing ports only removes explicit allows; it doesn’t block traffic. To truly restrict inbound traffic, switch to
pxf policy deny-alland then allow/deny as needed.
Port comments are saved in the journal and surface in pxf list ports --json to explain why a rule exists.
IP allow/deny (before NAT)
All IP subcommands take effect immediately on the live firewall; pxf apply later keeps the declarative snapshot aligned with those changes.
pxf ip allow <CIDR>/pxf ip remove-allowed <CIDR>— Bastion hosts/networks (always bypass blocks and closed ports).pxf ip deny <CIDR> [--ttl SECONDS] [--comment "REASON"]— Global block (affects redirected flows too).--ttl 0(default): Permanent block, journalled and persisted to disk--ttl N: Temporary block, stored only in the in-memory runtime sets (survivespxf apply, but not a reboot/systemd restart)--comment: Reason for blocking (optional)- Listing (
pxf list blocked-ip) enriches each IP with reverse DNS (reverse) and ISO country (country) when the target represents a single host and lookups succeed.
pxf ip remove-denied <CIDR>— Remove a blocked IP/CIDR.pxf ip clear-denied --force— Remove every blocked IP (changes apply immediately).
Redirects
pxf redirect add --from X --to Y --proto tcp|udp [--ipver 0|4|6] [--open-dst] [--comment "note"]Classic PREROUTING redirect.--open-dstalso opens destination port (handy for tests).--commentstores a short note that shows up inpxf list redirects.pxf redirect rm --from X --to Y --proto tcp|udp [--ipver 0|4|6]pxf tredirect add --from X --to Y --proto tcp|udp [--ipver 0|4|6] [--comment "note"]Transparent redirect: mark + allow only marked flows; destination port stays hidden externally. Comments here are also persisted and listed.pxf tredirect rm --from X --to Y --proto tcp|udp [--ipver 0|4|6]pxf local-redirect add --from X --to Y --proto tcp|udp [--ipver 0|4|6]OUTPUT (local) redirect — e.g.,curl localhost:80→:19080. (Removal depends on backend support and can be added later.)
firewalld (best-effort helpers)
pxf firewalld status—active|inactive|failed+enabled|disabled|masked.pxf firewalld disable [--mask]— Stop + disable (optionally mask) the unit.pxf firewalld enable— Unmask + enable + start.
Rule management
pxf rule delete <UUID>— Remove a specific rule (apply required to enforce)
Presets
-
pxf preset cpanel— Applies a predefined configuration for cPanel/WHM servers:- clears state (reset --allow-all),
- sets a secure baseline (policy deny-all + icmp allow-essential --v both),
- opens web ports (80/443),
- cPanel/WHM/Webmail/WebDAV (2077, 2078, 2082, 2083, 2086, 2087, 2095, 2096),
- SSH (detect from sshd_config, default 22),
- DNS (53 tcp/udp),
- Mail (25, 465, 587, 110, 995, 143, 993, 4190),
- FTP (21)
The preset does not apply the changes; run
pxf applyto enforce.